package com.whcoding.test.config;

import com.whcoding.test.pojo.ThreadPoolProperties;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @program: spring-boot-learning
 * @description:
 * @author: whcoding
 * @create: 2022-05-30 10:38
 **/
@Configuration
public class ThreadPoolConfig {

	@Bean(name = "scheduleThreadPool")
	@ConfigurationProperties(prefix = "thread.pool.schedule")
	public ThreadPoolProperties scheduleThreadPool() {
		return new ThreadPoolProperties();
	}

	@Bean(name = "taskScheduler")
	public TaskScheduler taskScheduler(@Qualifier("scheduleThreadPool") ThreadPoolProperties scheduleThreadPool) {
		ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
		taskScheduler.setPoolSize(scheduleThreadPool.getCorePoolSize());
		taskScheduler.setThreadFactory(new BasicThreadFactory.Builder().namingPattern(scheduleThreadPool.getNamePrefix()).build());
		return taskScheduler;
	}

	/**
	 * 执行异步任务
 	 */
	@Bean("taskExecutor")
	public Executor taskExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(4);
		executor.setMaxPoolSize(20);
		executor.setQueueCapacity(1000);
		executor.setKeepAliveSeconds(60);
		executor.setThreadNamePrefix("ASYNC-TASK-THREAD-");
		executor.setWaitForTasksToCompleteOnShutdown(true);
		executor.setRejectedExecutionHandler(
				new ThreadPoolExecutor.CallerRunsPolicy());
		executor.initialize();
		return executor;
	}
}
